package com.um.jdy.app.user.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.common.models.AlipayTradeCreateResponse;
import com.baomidou.lock.annotation.Lock4j;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.um.jdy.app.charge.manager.PBOrderManager;
import com.um.jdy.baofu.api.BaofuPayService;
import com.um.jdy.common.baofu.entity.po.BaofuRefund;
import com.um.jdy.common.baofu.service.BaofuRefundService;
import com.um.jdy.common.charge.service.OrderService;
import com.um.jdy.common.commons.manager.WxManager;
import com.um.jdy.app.user.entity.dto.TotalDepositDTO;
import com.um.jdy.app.user.entity.dto.WalletListQuery;
import com.um.jdy.app.user.entity.dto.WalletRechargeParam;
import com.um.jdy.app.user.entity.vo.DepositCashoutVO;
import com.um.jdy.app.user.entity.vo.UserBillListVO;
import com.um.jdy.app.user.entity.vo.WalletDetailVO;
import com.um.jdy.app.user.entity.vo.WalletListVO;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.charge.code.OrderCode;
import com.um.jdy.common.charge.entity.po.DepositOrder;
import com.um.jdy.common.charge.entity.vo.DepositOrderVO;
import com.um.jdy.common.charge.enums.OrderEnum;
import com.um.jdy.common.charge.service.DepositOrderService;
import com.um.jdy.common.finance.entity.po.PlatformBill;
import com.um.jdy.common.finance.entity.po.PlatformProfitBill;
import com.um.jdy.common.finance.entity.po.UserBill;
import com.um.jdy.common.finance.enums.FinancialEnum;
import com.um.jdy.common.finance.service.PlatformBillService;
import com.um.jdy.common.finance.service.PlatformProfitBillService;
import com.um.jdy.common.finance.service.UserBillService;
import com.um.jdy.common.member.code.UserCode;
import com.um.jdy.common.member.entity.po.MemberUser;
import com.um.jdy.common.member.entity.po.RechargeOrder;
import com.um.jdy.common.member.entity.po.RechargePackage;
import com.um.jdy.common.member.entity.po.Wallet;
import com.um.jdy.common.member.entity.vo.RechargePackageVO;
import com.um.jdy.common.member.enums.PayEnum;
import com.um.jdy.common.member.enums.WalletEnum;
import com.um.jdy.common.member.service.MemberUserService;
import com.um.jdy.common.member.service.RechargeOrderService;
import com.um.jdy.common.member.service.RechargePackageService;
import com.um.jdy.common.member.service.WalletService;
import com.um.jdy.common.platform.entity.po.App;
import com.um.jdy.common.platform.service.AppService;
import com.um.springboot.starter.code.CommonCode;
import com.um.springboot.starter.config.SystemSQL;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.properties.HshProperties;
import com.um.springboot.starter.utils.EnumUtil;
import com.um.springboot.starter.utils.OrderUtil;
import com.um.springboot.starter.utils.PayUtil;
import com.um.springboot.starter.utils.StringUtil;
import com.um.weixin.pay.service.WxBasePayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Title
 * @Description
 * @Author renjunwei
 * @Date 2023/5/22 16:04
 */
@Slf4j
@Service
public class WalletManager {

    @Autowired
    HshProperties hshProperties;

    @Autowired
    MemberUserService userService;

    @Autowired
    WalletService walletService;

    @Autowired
    RechargePackageService rechargePackageService;

    @Autowired
    RechargeOrderService rechargeOrderService;

    @Autowired
    HttpServletRequest request;

    @Autowired
    UserBillService userBillService;

    @Autowired
    PlatformBillService platformBillService;

    @Autowired
    PlatformProfitBillService platformProfitBillService;

    @Autowired
    OrderService orderService;

    @Autowired
    WxBasePayService wxPayService;

    @Autowired
    WxManager wxManager;

    @Autowired
    DepositOrderService depositOrderService;

    @Autowired
    PBOrderManager pbOrderManager;

    @Value("${spring.profiles.active}")
    public String Profile;
    @Autowired
    BaofuPayService baofuPayService;

    @Autowired
    AppService appService;
    @Autowired
    private BaofuRefundService baofuRefundService;

    /**
     * 查询钱包余额
     * @return
     */
    public WalletDetailVO get(){
        String userId = userService.get().getMemberUserId();

        WalletDetailVO vo = new WalletDetailVO();
        vo.setBalance(walletService.getBalance(userId,userService.get().getComId()));
        TotalDepositDTO deposit = walletService.getViewModel("get_total_deposit", TotalDepositDTO.class, new Object[]{userId,userService.getComId()});
        vo.setDeposit(deposit.getDeposit());
        vo.setDepositFreeze(deposit.getDepositFreeze());
        vo.setDepositStatus(deposit.getDepositFreeze() > 0 ? WalletDetailVO.DepositStatus.Freeze : WalletDetailVO.DepositStatus.Normal);

        return vo;
    }


    /**
     * 查询钱包余额
     * @return
     */
    public Integer getBalance(){
        String userId = userService.get().getMemberUserId();
        return walletService.getBalance(userId,userService.get().getComId());
    }

    public Integer getCanCashoutBalance(){
        String userId = userService.get().getMemberUserId();
        return walletService.getCanCashoutBalance(userId,userService.get().getComId());
    }

    /**
     * 查询充值套餐列表
     * @return
     */
    public List<RechargePackageVO> getPackageList(){
        List<RechargePackage> list = rechargePackageService.getList("is_enable", YesOrNo.Yes.name(),
                "sort_no", "asc");
        return BeanUtil.copyToList(list, RechargePackageVO.class);
    }

    /**
     * 查询充值套餐列表
     * @return
     */
    public Map recharge(WalletRechargeParam param){
        RechargePackage rechargePackage = rechargePackageService.getEntity(param.getMemberRechargePackageId());
        if(null == rechargePackage){
            throw new ServiceException(OrderCode.NoPackage);
        }

        if(!(PayEnum.PayWay.Alipay.name().equals(param.getPayWay().name()) || PayEnum.PayWay.Wxpay.name().equals(param.getPayWay().name()))){
            throw new ServiceException(OrderCode.UnsupportPayWay);
        }

        MemberUser user = userService.get();

        String outTradeNo = OrderUtil.getWxOrderNo();
        int payAmount = rechargePackage.getPayAmount();
        int rechargeAmount = rechargePackage.getRechargeAmount();
        int giftAmount = rechargePackage.getGiftAmount();

        RechargeOrder rechargeOrder = new RechargeOrder();
        rechargeOrder.setOutTradeNo(outTradeNo);
        rechargeOrder.setOrderNo(OrderUtil.getOrderNo());
        rechargeOrder.setMemberUserId(user.getMemberUserId());
        rechargeOrder.setRechargeAmount(rechargeAmount);
        rechargeOrder.setPayAmount(payAmount);
        rechargeOrder.setGiftAmount(giftAmount);
        rechargeOrder.setMemberRechargePackageId(param.getMemberRechargePackageId());
        rechargeOrder.setCreateTime(DateUtil.date());
        rechargeOrder.setPayWay(param.getPayWay().name());
        rechargeOrderService.save(rechargeOrder);


        if (PayEnum.PayWay.Alipay.name().equals(param.getPayWay().name())) {
            String notifyUrl = StrUtil.builder(hshProperties.getConfig().getDomain(), "/api/v1/user/wallet/alipay/notify").toString();

            //支付宝支付
            AlipayTradeCreateResponse alipayTradeCreateResponse = null;
            try {
                alipayTradeCreateResponse = Factory.Payment.Common()
                        .asyncNotify(notifyUrl)
                        .optional("timeout_express", "10m") //订单超时时间
                        .create(PayEnum.Title.Package.getValue(), outTradeNo, PayUtil.toDoubleAmountStr(payAmount), user.getAlipayUserId());
            } catch (Exception e) {
                log.error("支付宝创建订单失败", e);
                throw new ServiceException("支付宝创建订单失败");
            }

            log.info("支付宝下单：" + cn.hutool.json.JSONUtil.toJsonStr(alipayTradeCreateResponse));

            if (!ResponseChecker.success(alipayTradeCreateResponse)) {
                throw new ServiceException(CommonCode.Failed.getCode(), alipayTradeCreateResponse.getSubMsg());
            }

            return alipayTradeCreateResponse.toMap();

        } else{
            /**todo 改成宝付支付
            String notifyUrl = StrUtil.builder(hshProperties.getConfig().getDomain(),
                    "/api/v1/user/wallet/wxpay/notify/", userService.getComId()).toString();

            WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = null;
            try {
                wxManager.getPayService(userService.getComId());
                jsapiResult = wxPayService.createOrderByJsapi(outTradeNo, user.getMiniOpenId(),
                        PayUtil.toTotalFee(payAmount), PayEnum.Title.Package.getValue(), notifyUrl);
            } catch (WxPayException e) {
                log.error("支付失败：",e);
                throw new ServiceException(e.getCustomErrorMsg());
            }

            Map<String, Object> returnData = BeanUtil.beanToMap(jsapiResult, true, true);
            */
            String type ="wallet";
            App app = appService.getEntity("com_id", userService.getComId());
            Map<String, Object> returnData = baofuPayService.createOrderByJsapi(outTradeNo,PayUtil.toTotalFee(payAmount),PayEnum.Title.Package.getValue(),user.getMiniOpenId(),app.getMiniAppId(),app.getWxMchId(),type,userService.getComId());
            //Map<String, Object> returnData = null;

            return returnData;
        }
    }

    /**
     * 充值套餐回调
     *
     * @param outTradeNo
     * @param payTime
     */
    @Transactional
    public void rechargeNotify(String outTradeNo, Date payTime) {
        log.info("=====充值套餐回调：" + outTradeNo);

        RechargeOrder order = rechargeOrderService.getRow("out_trade_no", outTradeNo);
        if(order == null){
            log.info("=====充值套餐回调,订单不存在：" + outTradeNo);
            return;
        }

        if(order.getStatus().equals(WalletEnum.OrderStatus.Payed.name())){
            log.info("=====充值套餐回调,订单已支付：" + outTradeNo);
            return;
        }

        //变更订单状态
        order.setStatus(WalletEnum.OrderStatus.Payed.name());
        order.setPayTime(payTime);
        rechargeOrderService.updateRow(order);

        //记录钱包流水，金额为充值到账金额
        Wallet wallet = new Wallet();
        wallet.setComId(order.getComId());
        wallet.setMemberUserId(order.getMemberUserId());
        wallet.setOrderNo(order.getOrderNo());
        wallet.setNo(order.getOrderNo());
        wallet.setType(FinancialEnum.IncomeOrExpend.Income.name());
        wallet.setAmount(order.getRechargeAmount());
        wallet.setStatus(FinancialEnum.BillStatus.Effective.name());
        wallet.setEvent(FinancialEnum.WalletBillEvent.Recharge.name());
        wallet.setCreateTime(DateUtil.date());
        walletService.saveRow(wallet);

        //记录账户流水，金额为支付金额
        //充值余额
        UserBill userBill = new UserBill();
        userBill.setComId(order.getComId());
        userBill.setMemberUserId(order.getMemberUserId());
        userBill.setNo(OrderUtil.getOrderNo());
        userBill.setOutTradeNo(outTradeNo);
        userBill.setOrderNo(order.getOrderNo());
        userBill.setAmount(order.getPayAmount());
        userBill.setType(FinancialEnum.IncomeOrExpend.Expend.name());//收入支出类型：0-收入，1-支出
        userBill.setEvent(FinancialEnum.UserBillEvent.Recharge.name());
        userBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
        userBill.setCreateTime(DateUtil.date());
        userBillService.saveRow(userBill);

        //插入平台收支流水：套餐充值
        PlatformBill platformBill = new PlatformBill();
        platformBill.setComId(order.getComId());
        platformBill.setNo(OrderUtil.getOrderNo());
        platformBill.setOutTradeNo(outTradeNo);
        platformBill.setOrderNo(order.getOrderNo());
        platformBill.setAmount(order.getPayAmount());
        platformBill.setType(FinancialEnum.IncomeOrExpend.Income.name());//收入支出类型：0-收入，1-支出
        platformBill.setEvent(FinancialEnum.PlatformBillEvent.Recharge.name());
        platformBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
        platformBill.setCreateTime(DateUtil.date());
        platformBillService.saveRow(platformBill);

        //插入平台收益流水：充值赠送
        if(order.getGiftAmount() > 0) {
            Wallet gift = new Wallet();
            gift.setComId(order.getComId());
            gift.setMemberUserId(order.getMemberUserId());
            gift.setOrderNo(order.getOrderNo());
            gift.setNo(order.getOrderNo());
            gift.setType(FinancialEnum.IncomeOrExpend.Income.name());
            gift.setAmount(order.getGiftAmount());
            gift.setStatus(FinancialEnum.BillStatus.Effective.name());
            gift.setEvent(FinancialEnum.WalletBillEvent.RechargeGift.name());
            gift.setCreateTime(DateUtil.date());
            walletService.saveRow(gift);


            PlatformProfitBill profitBill = new PlatformProfitBill();
            profitBill.setComId(order.getComId());
            profitBill.setNo(OrderUtil.getOrderNo());
            profitBill.setOutTradeNo(outTradeNo);
            profitBill.setOrderNo(order.getOrderNo());
            profitBill.setAmount(order.getGiftAmount());
            profitBill.setType(FinancialEnum.IncomeOrExpend.Expend.name());//收入支出类型：0-收入，1-支出
            profitBill.setEvent(FinancialEnum.PlatformProfitBillEvent.RechargeGift.name());
            profitBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
            profitBill.setCreateTime(DateUtil.date());
            platformProfitBillService.saveRow(profitBill);
        }

        //更新汽车充电中的余额
        MemberUser memberUser = userService.getRow(order.getMemberUserId());
        if(memberUser != null) {
            Integer balance = walletService.getBalance(memberUser.getMemberUserId(),memberUser.getComId());
            orderService.remoteUpdateEVChargeBalance(order.getMemberUserId(),memberUser.getNo(),balance);
        }

    }

    /**
     * 查询钱包流水
     * @param query
     * @return
     */
    public Page<WalletListVO> getWalletPage(WalletListQuery query){

        String sql = SystemSQL.getInstance().getSystemSQL("get_wallet_bill_page");
        String sqlSum = SystemSQL.getInstance().getSystemSQL("get_wallet_bill_count");

        String condition = "";
        List params = new ArrayList<>();
        params.add(userService.get().getMemberUserId());
        params.add(StrUtil.blankToDefault(query.getType(), "%"));
        params.add(userService.getComId());

        if(!StrUtil.isEmpty(query.getBegin_date())){
            condition += " and DATE_FORMAT(create_time,'%Y-%m')>=?";
            params.add(query.getBegin_date());
        }
        if(!StrUtil.isEmpty(query.getEnd_date())){
            condition += " and DATE_FORMAT(create_time,'%Y-%m')<=?";
            params.add(query.getEnd_date());
        }

        sql = sql.replace("[condition]",condition);
        sqlSum = sqlSum.replace("[condition]",condition);

        Page<WalletListVO> page = new Page(query);
        page = walletService.getViewModelPageBySql(page, sql, sqlSum, WalletListVO.class, params.toArray());

        List<WalletListVO> result = new ArrayList();

        for (WalletListVO item : page.getResult()) {

            if (StrUtil.isNotEmpty(item.getYears()) && !item.getYears().equals(query.getPrev_years())) {

                WalletListVO walletListVO = new WalletListVO();
                walletListVO.setYears(item.getYears());
                walletListVO.setDataType(WalletListVO.DataType.Years);
                result.add(walletListVO);

                query.setPrev_years(item.getYears());
            }

            item.setDataType(WalletListVO.DataType.Bill);
            item.setEvent(FinancialEnum.WalletBillEvent.valueOf(item.getEvent()).getValue());

            result.add(item);
        }

        page.setResult(result);
        return page;
    }

    /**
     * 查询钱包流水
     * @param query
     * @return
     */
    public Page<UserBillListVO> getBillPage(WalletListQuery query){

        String sql = SystemSQL.getInstance().getSystemSQL("get_user_bill_page");
        String sqlSum = SystemSQL.getInstance().getSystemSQL("get_user_bill_count");

        String condition = "";
        List params = new ArrayList<>();
        params.add(userService.get().getMemberUserId());
        params.add(StrUtil.blankToDefault(query.getType(), "%"));
        params.add(userService.getComId());

        if(!StrUtil.isEmpty(query.getBegin_date())){
            condition += " and DATE_FORMAT(create_time,'%Y-%m')>=?";
            params.add(query.getBegin_date());
        }
        if(!StrUtil.isEmpty(query.getEnd_date())){
            condition += " and DATE_FORMAT(create_time,'%Y-%m')<=?";
            params.add(query.getEnd_date());
        }

        sql = sql.replace("[condition]",condition);
        sqlSum = sqlSum.replace("[condition]",condition);

        Page<UserBillListVO> page = new Page(query);
        page = walletService.getViewModelPageBySql(page, sql, sqlSum, UserBillListVO.class, params.toArray());

        List<UserBillListVO> result = new ArrayList();

        for (UserBillListVO item : page.getResult()) {

            if (StrUtil.isNotEmpty(item.getYears()) && !item.getYears().equals(query.getPrev_years())) {

                UserBillListVO walletListVO = new UserBillListVO();
                walletListVO.setYears(item.getYears());
                walletListVO.setDataType(UserBillListVO.DataType.Years);
                result.add(walletListVO);

                query.setPrev_years(item.getYears());
            }

            item.setDataType(UserBillListVO.DataType.Bill);
            item.setEvent(FinancialEnum.UserBillEvent.valueOf(item.getEvent()).getValue());

            result.add(item);
        }

        page.setResult(result);
        return page;
    }

    /**
     * 押金提现
     * @return
     */
    public DepositCashoutVO depositCashout(){
        String userId = userService.get().getMemberUserId();
        TotalDepositDTO deposit = walletService.getViewModel("get_total_deposit", TotalDepositDTO.class, new Object[]{userId,userService.get().getComId()});

        if(deposit.getDepositFreeze() > 0){
            throw new ServiceException("还有未完成的订单，押金冻结中，暂不能提现！");
        }

        List<DepositOrder> depositOrders = depositOrderService.getList(new String[]{"member_user_id", "pay_status", "return_status"},
                new String[]{userId, PayEnum.Status.Payed.name(), YesOrNo.No.name()},
                new String[]{"create_time"}, new String[]{"desc"});
        if(depositOrders.size() == 0){
            throw new ServiceException("没有待提现的押金！");
        }

        DepositOrder depositOrder = depositOrders.get(0);
        boolean result = pbOrderManager.returnDepositOrder(depositOrder);

        DepositCashoutVO vo = new DepositCashoutVO();
        vo.setDepositOrder(BeanUtil.toBean(depositOrder, DepositOrderVO.class));
        vo.setCashoutResult(result);
        return vo;
    }

    /**
     * 余额提现
     * @return
     */
    @Lock4j(keys = "#userId")
    public Response cashout(String userId,String comId){

        if(orderService.getUnFinishEVOrders(userId,comId) > 0){
            return Response.failed(UserCode.NoCashoutUnFinishOrder);
        }

        // 1.查询待退款金额
        int balance = walletService.getCanCashoutBalance(userId,comId);
        if(balance == 0){
            return Response.failed(UserCode.NoBalanceForCashout);
        }

        // 2.查询所有可退款充值订单
        List<RechargeOrder> orderList = walletService.getViewModelList("get_can_cashout_recharge_order_list",RechargeOrder.class, new String[]{userId,userService.getComId()});
        if(orderList.size() <= 0){
            return Response.failed(UserCode.NoCashoutRechargeOrder);
        }

        // 3.开始退款
        for (RechargeOrder order : orderList){
            int canReturnAmount = order.getPayAmount() - order.getReturnAmount();
            if(canReturnAmount >= balance && refund(order, balance)){
                return Response.success();
            }

            if(refund(order, canReturnAmount)){
                balance -= canReturnAmount;
            }
        }
        return Response.success();
    }


    /**
     * 退款
     * @param order
     * @param returnAmount
     * @return
     */
    private boolean refund(RechargeOrder order, int returnAmount){
        String orderNo = order.getOrderNo();
        int payAmount = order.getPayAmount();//微信充值的订单金额
        if(returnAmount + order.getReturnAmount() > payAmount){
            log.error("退款金额大于充值支付金额,当前已退款金额为："+order.getReturnAmount()/100);
            return false;
        }

        String outTradeNo = order.getOutTradeNo();
        String returnOutTradeNo = OrderUtil.getWxOrderNo();
        boolean refundSuccess = false;
        String returnMsg = "";
        boolean isBaofu=true;
        if(!Profile.equals("dev")) {//开放环境不退款
            if (order.getPayWay().equals(PayEnum.PayWay.Alipay.name())) {
//                // 支付宝退款
//                Map refundResult = new HashMap();
//                try {
//                    refundResult = payService.refund(outTradeNo, payUtil.toDoubleAmount(returnAmount));
//                    log.info("支付宝充值退款返回:" + JSONUtil.toJSONString(refundResult));
//                    refundSuccess = true;
//                } catch (Exception e) {
//                    returnMsg = StringUtil.getTrim(refundResult.get("sub_msg"));
//                }
            } else if(order.getPayWay().equals(PayEnum.PayWay.Wxpay.name())) {
                /** todo 修改为宝付退款
                try {
                    int totalFee = PayUtil.toTotalFee(payAmount);//支付的订单金额
                    int returnFee = PayUtil.toTotalFee(returnAmount);//退回金额

                    wxManager.getPayService(order.getComId());
                    wxPayService.refundOrder(outTradeNo, returnOutTradeNo, totalFee, returnFee);
                    refundSuccess = true;

                } catch (WxPayException e) {
                    refundSuccess = false;
                }*/
                try{
                    String type ="wallet";
                    baofuPayService.refundOrder(outTradeNo, returnOutTradeNo, PayUtil.toTotalFee(payAmount),PayUtil.toTotalFee(returnAmount),type,order.getComId());
                    refundSuccess = true;
                    isBaofu = false;
                    BaofuRefund baofuRefund = new BaofuRefund();
                    baofuRefund.setComId(order.getComId());
                    baofuRefund.setRefundAmount(returnAmount);
                    baofuRefund.setOutRefundNo(returnOutTradeNo);
                    baofuRefund.setRefundState("REFUND");
                    baofuRefund.setOutTradeNo(outTradeNo);
                    baofuRefund.setType(type);
                    baofuRefundService.addRefund(baofuRefund);
                }catch (ServiceException e){
                    refundSuccess = false;
                }

            }
        }else{
            refundSuccess = true;
        }

        if(!refundSuccess) {
            log.error("退款失败："+returnMsg);
            return false;
        }

        order.setReturnTime(new Date());
        order.setReturnAmount(order.getReturnAmount()+returnAmount);
        rechargeOrderService.saveRow(order);
        //宝付退款走回调 todo
        if(isBaofu){
            //记录钱包流水：余额提现
            Wallet memberWallet = new Wallet();
            memberWallet.setComId(order.getComId());
            memberWallet.setMemberUserId(order.getMemberUserId());
            memberWallet.setOrderNo(order.getOrderNo());
            memberWallet.setNo(OrderUtil.getOrderNo());
            memberWallet.setAmount(returnAmount);
            memberWallet.setType(FinancialEnum.IncomeOrExpend.Expend.name());
            memberWallet.setEvent(FinancialEnum.WalletBillEvent.RechargeRedund.name());
            memberWallet.setStatus(FinancialEnum.BillStatus.Effective.name());
            memberWallet.setCreateTime(DateUtil.date());
            walletService.saveRow(memberWallet);

            //插入用户账单流水：余额提现
            UserBill userBill = new UserBill();
            userBill.setComId(order.getComId());
            userBill.setMemberUserId(order.getMemberUserId());
            userBill.setNo(OrderUtil.getOrderNo());
            userBill.setOutTradeNo(returnOutTradeNo);
            userBill.setOrderNo(orderNo);
            userBill.setAmount(returnAmount);
            userBill.setType(FinancialEnum.IncomeOrExpend.Income.name());//收入支出类型：0-收入，1-支出
            userBill.setEvent(FinancialEnum.UserBillEvent.RechargeRedund.name());
            userBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
            userBill.setCreateTime(DateUtil.date());
            userBillService.saveRow(userBill);

            //插入平台账单流水：余额提现
            PlatformBill platformBill = new PlatformBill();
            platformBill.setComId(order.getComId());
            platformBill.setNo(OrderUtil.getOrderNo());
            platformBill.setOutTradeNo(returnOutTradeNo);
            platformBill.setOrderNo(orderNo);
            platformBill.setAmount(returnAmount);
            platformBill.setType(FinancialEnum.IncomeOrExpend.Expend.name());//收入支出类型：0-收入，1-支出
            platformBill.setEvent(FinancialEnum.PlatformBillEvent.PackageRefund.name());
            platformBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
            platformBill.setCreateTime(DateUtil.date());
            platformBillService.saveRow(platformBill);

            int giftAmount = (int)(order.getGiftAmount() * (returnAmount * 1.0 / order.getPayAmount()));
            //订单存在赠送金额，则需要按比例退掉赠送金额
            if(giftAmount > 0){

                Wallet giftWallet = new Wallet();
                giftWallet.setComId(order.getComId());
                giftWallet.setMemberUserId(order.getMemberUserId());
                giftWallet.setOrderNo(order.getOrderNo());
                giftWallet.setNo(OrderUtil.getOrderNo());
                giftWallet.setAmount(giftAmount);
                giftWallet.setType(FinancialEnum.IncomeOrExpend.Expend.name());
                giftWallet.setEvent(FinancialEnum.WalletBillEvent.GiftRefund.name());
                giftWallet.setStatus(FinancialEnum.BillStatus.Effective.name());
                giftWallet.setCreateTime(DateUtil.date());
                walletService.saveRow(giftWallet);

                PlatformProfitBill profitBill = new PlatformProfitBill();
                profitBill.setComId(order.getComId());
                profitBill.setNo(OrderUtil.getOrderNo());
                profitBill.setOutTradeNo(returnOutTradeNo);
                profitBill.setOrderNo(orderNo);
                profitBill.setAmount(giftAmount);
                profitBill.setType(FinancialEnum.IncomeOrExpend.Income.name());//收入支出类型：0-收入，1-支出
                profitBill.setEvent(FinancialEnum.PlatformProfitBillEvent.GiftRefund.name());
                profitBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
                profitBill.setCreateTime(DateUtil.date());
                platformProfitBillService.saveRow(profitBill);
            }
        }


        return true;
    }

    public void wxPayNotify(HttpServletRequest request, String comId){

        WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = null;
        try {
            wxManager.getPayService(comId);
            wxPayOrderNotifyV3Result = wxPayService.parseOrderNotify(request);
        } catch (WxPayException e) {
            log.error("解析微信支付通知失败", e);
            return;
        }

        WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
        if(null == result){
            log.error("解析微信支付通知结果为null");
            return;
        }

        rechargeNotify(result.getOutTradeNo(),
                DateUtil.parse(result.getSuccessTime()));

    }

    /**
     * 支付宝支付回调
     * @param request
     * @throws Exception
     */
    public void aliPayNotify(HttpServletRequest request) {

        Map<String, String> parameters = ServletUtil.getParamMap(request);
        log.info("支付宝充值支付回调异步通知：{}", cn.hutool.json.JSONUtil.toJsonStr(parameters));

        boolean verifyResult = false;
        try {
            verifyResult = Factory.Payment.Common().verifyNotify(parameters);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        if (!verifyResult || !StrUtil.equals("TRADE_SUCCESS", parameters.get("trade_status"))) {
            log.error("支付宝支付异步通知验签未通过！");
        }

        //处理订单支付后续
        String outTradeNo = parameters.get("out_trade_no");
        Date payTime = DateUtil.parse(parameters.get("gmt_payment"));

        rechargeNotify(outTradeNo, payTime);

    }


    public void baofuWxPayNotify(String outTradeNO,String successTime, String comId){


        rechargeNotify(outTradeNO, DateUtil.parse(successTime));

    }

}
